#pragma once
#include "XamlParserContext.h"
#include "XamlTextReaderSettings.h"
#include "XamlPropertyName.h"
#include "XamlScannerNode.h"

class XamlSortedAttributes
{
public: 
	enum ScannerAttributeKind
	{
		sakNamespace = 0x0,
		sakUid = 0x1,
		sakName = 0x2,
		sakDirective = 0x3,
		sakXmlSpace = 0x4,
		sakEvent = 0x5,
		sakProperty = 0x6,
		sakUnknown = 0x7,
		sakNumberOfBuckets = 0x8
	};

	enum XamlNamespaceKind
	{
		xnkNotANamespace = 0x0,
		xnkDefaultNamespace = 0x1,
		xnkDefinedNamespace = 0x2
	};

	XamlSortedAttributes(const xshared_ptr<XamlParserContext> & inParserContext, const xshared_ptr<XamlTextReaderSettings> & spSettings);
	~XamlSortedAttributes();
	HRESULT Reset();
	HRESULT Add(const XamlLineInfo & inLineInfo, const XamlScannerNode & elementNode, const xshared_ptr<XamlPropertyName> & inPropertyName, const xshared_ptr<XamlText> & inAttributeText);
	enum XamlSortedAttributes::ScannerAttributeKind IdentifyNode(const XamlScannerNode & elementNode);
	XUINT32 GetBucketSize(enum XamlSortedAttributes::ScannerAttributeKind kind);
	XUINT32 GetSize();

	xvector<XamlScannerNode>::iterator GetBucketIteratorBegin(enum XamlSortedAttributes::ScannerAttributeKind kind);
	xvector<XamlScannerNode>::iterator GetBucketIteratorEnd(enum XamlSortedAttributes::ScannerAttributeKind kind);

	HRESULT IsXmlNamespaceDefinition(const xshared_ptr<CXString> & inPrefix, const xshared_ptr<CXString> & inName, enum XamlSortedAttributes::XamlNamespaceKind & namespaceKind);
	HRESULT GetXmlNamespaceDefinitionUri(enum XamlSortedAttributes::XamlNamespaceKind inKind, const xshared_ptr<XamlPropertyName> & inPropertyName, const xshared_ptr<CXString> & inAttributeValue, xshared_ptr<CXString> & outDefiningPrefix, xshared_ptr<CXString> & outUri);
	XBOOL IsFirstElement();
	HRESULT IsMarkupCompatabilityNamespace(const xshared_ptr<XamlNamespace> & inNamespace, XBOOL & outbIsMarkupCompatibility);
	HRESULT AddIgnoredNamespaces(const xshared_ptr<CXString> & inNamespacePrefixesToIgnore);
	void SetFoundXKeyDirective(XBOOL bFound);
	XBOOL GetFoundXKeyDirective();
	XBOOL IsFoundXKeyDirectiveValid();
private: 
	HRESULT IsXmlSpace(const xshared_ptr<XamlPropertyName> & inName, XBOOL & bIsXmlSpace);
	HRESULT AddIgnoredPrefix(const xshared_ptr<CXString> & inPrefixToIgnore);
	HRESULT IsRuntimeNameProperty(const xshared_ptr<XamlProperty> & inProperty, const xshared_ptr<XamlType> & inTagType, XBOOL & bIsRuntimeName);
	HRESULT GetXamlAttributeProperty(const xshared_ptr<XamlPropertyName> & inPropertyName, const xshared_ptr<XamlType> & inTagType, const xshared_ptr<CXString> & spOwnerPrefix, const xshared_ptr<XamlNamespace> & inOwnerNamespace, XBOOL & outbIsIgnored, xshared_ptr<XamlProperty> & outProperty);
	HRESULT GetErrorService(xshared_ptr<ParserErrorReporter> & outErrorService);
	HRESULT ReportError(XUINT32 errorCode, const xshared_ptr<CXString> & inssParam1, const xshared_ptr<CXString> & inssParam2, const XamlLineInfo & lineInfo);
	HRESULT ReportError(XUINT32 errorCode, const xshared_ptr<CXString> & inssParam1, const XamlLineInfo & lineInfo);
	HRESULT ReportError(XUINT32 errorCode, const XamlLineInfo & lineInfo);
	XamlScannerNode m_WorkingAttributeNode;

	xvector<XamlScannerNode> m_Buckets[8];
	xshared_ptr<XamlParserContext> m_ParserContext;

	XBOOL m_shouldProcessUid:1;
	XBOOL m_bFoundXKeyDirective:1;
	XBOOL m_bFoundXKeyDirectiveValid:1;


};